use std::fmt::{Display, Formatter, write};
use actix_web::error::ResponseError;
use actix_web::http::{header, StatusCode};
use actix_web::{Error, HttpResponse};
use serde::Serialize;

#[derive(Debug, Serialize)]
pub enum MyError {
    DBError(String),
    ActixError(String),
    NotFound(String),
}

#[derive(Debug, Serialize)]
pub struct MyErrorResponse {
    error_message: String,
}

impl MyError {
    fn error_response(&self) -> String {
        match self {
            MyError::DBError(msg) => {
                println!("database error  {}", msg);
                "DataBase Error".into()
            }
            MyError::ActixError(msg) => {
                println!("ActixError   {}", msg);
                "ActixError".into()
            }
            MyError::NotFound(msg) => {
                println!("Not found   {}", msg);
                "Not found ".into()
            }

            _ => {
                "内部错误".into()
            }
        }
    }
}


impl Display for MyError {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self)
    }
}

impl ResponseError for MyError {
    fn status_code(&self) -> StatusCode {
        match self {
            MyError::DBError(msg) | MyError::ActixError(msg) => StatusCode::INTERNAL_SERVER_ERROR,
            MyError::NotFound(m) => StatusCode::NOT_FOUND,
            _ => StatusCode::NOT_FOUND,
        }
    }

    fn error_response(&self) -> HttpResponse {
        HttpResponse::build(self.status_code())
            .json(MyErrorResponse {
                error_message: self.error_response()
            })
    }
}


// 转成自定义异常
impl From<actix_web::error::Error> for MyError {
    fn from(value: Error) -> Self {
        MyError::ActixError(value.to_string())
    }
}


impl From<sqlx::error::Error> for MyError {
    fn from(value: sqlx::Error) -> Self {
        MyError::DBError(value.to_string())
    }
}